package com.lineage.server.datatables;

import com.lineage.DatabaseFactory;
import com.lineage.server.model.Instance.L1ItemInstance;
import com.lineage.server.model.Instance.L1MonsterInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.L1Character;
import com.lineage.server.model.L1Object;
import com.lineage.server.serverpackets.S_ServerMessage;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1DropScreen;
import com.lineage.server.templates.L1Item;
import com.lineage.server.utils.PerformanceTimer;
import com.lineage.server.utils.SQLUtil;
import com.lineage.server.world.World;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DropScreenTable {
  private static final Log _log = LogFactory.getLog(DropScreenTable.class);
  
  private final Map<Integer, L1DropScreen> _list;
  
  private static final ArrayList<Integer> _npcList = new ArrayList<>();
  
  private static DropScreenTable _instance;
  
  public static DropScreenTable get() {
    if (_instance == null)
      _instance = new DropScreenTable(); 
    return _instance;
  }
  
  public static void reload() {
    DropScreenTable oldInstance = _instance;
    _instance = new DropScreenTable();
    oldInstance._list.clear();
    oldInstance = null;
  }
  
  private DropScreenTable() {
    this._list = new HashMap<>();
    load();
  }
  
  private void load() {
    PerformanceTimer timer = new PerformanceTimer();
    Connection con = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    try {
      con = DatabaseFactory.get().getConnection();
      pstm = con.prepareStatement("SELECT * FROM `w_参予击杀奖励`");
      rs = pstm.executeQuery();
      while (rs.next()) {
        int key = rs.getInt("id");
        int npc_id = rs.getInt("npc_id");
        int item_id = rs.getInt("item_id");
        int min = rs.getInt("min");
        int max = rs.getInt("max");
        int random = rs.getInt("random");
        int enchant_min = rs.getInt("enchant_min");
        int enchant_max = rs.getInt("enchant_max");
        boolean is_attack = rs.getBoolean("is_attack");
        if (check_item(item_id)) {
          L1DropScreen drop = new L1DropScreen(npc_id, item_id, min, max, random, enchant_min, 
              enchant_max, is_attack);
          this._list.put(Integer.valueOf(key), drop);
          if (_npcList.contains(Integer.valueOf(npc_id)))
            continue; 
          _npcList.add(Integer.valueOf(npc_id));
        } 
      } 
    } catch (SQLException e) {
      _log.error(e.getLocalizedMessage(), e);
    } finally {
      SQLUtil.close(rs);
      SQLUtil.close(pstm);
      SQLUtil.close(con);
    } 
    _log.info("载入掉落物品资料数量(全画面掉落): " + this._list.size() + "(" + timer.get() + "ms)");
  }
  
  private boolean check_item(int itemId) {
    L1Item itemTemplate = ItemTable.get().getTemplate(itemId);
    if (itemTemplate == null) {
      _log.info("掉落物品资料数量(全画面)错误物品->" + itemId);
      return false;
    } 
    return true;
  }
  
  public void runDropScreen(L1MonsterInstance mob, ArrayList<L1Character> acquisitorList) {
    if (this._list.isEmpty() || _npcList.isEmpty())
      return; 
    int npc_id = mob.getNpcId();
    if (!_npcList.contains(Integer.valueOf(npc_id)))
      return; 
    Iterator<Integer> iterator = this._list.keySet().iterator();
    while (iterator.hasNext()) {
      Integer key = iterator.next();
      L1DropScreen drop = this._list.get(key);
      if (drop.getMobid() == npc_id) {
        Iterator<L1PcInstance> iterator2 = World.get().getVisiblePlayer((L1Object)mob).iterator();
        while (iterator2.hasNext()) {
          L1PcInstance pc = iterator2.next();
          if (pc.isDead())
            continue; 
          if (drop.is_attack() && !acquisitorList.contains(pc))
            continue; 
          Random _random = new Random();
          int random = _random.nextInt(1000) + 1;
          if (drop.getChance() < random)
            continue; 
          int itemCount = drop.getMin();
          int addCount = drop.getMax() - itemCount + 1;
          if (addCount > 1)
            itemCount += _random.nextInt(addCount); 
          L1ItemInstance item = pc.getInventory().storeItem(drop.getItemid(), itemCount);
          if (pc.isInParty()) {
            Object[] pcs = pc.getParty().partyUsers().values().toArray();
            if (pcs.length <= 0)
              return; 
            Object[] array;
            int length = (array = pcs).length;
            int i = 0;
            while (i < length) {
              Object obj = array[i];
              if (obj instanceof L1PcInstance) {
                L1PcInstance tgpc = (L1PcInstance)obj;
                tgpc.sendPackets((ServerBasePacket)new S_ServerMessage(813, mob.getNameId(), 
                      String.valueOf(String.valueOf(item.getName())) + " (" + itemCount + ")", pc.getName()));
              } 
              i++;
            } 
            continue;
          } 
          pc.sendPackets((ServerBasePacket)new S_ServerMessage(143, mob.getNameId(), 
                String.valueOf(String.valueOf(item.getName())) + " (" + itemCount + ")"));
        } 
      } 
    } 
  }
}
